![]() | |
|
|
|
To access the contents, click the chapter and section titles.
Bug Proofing Visual Basic: A Guide to Error Handling and Prevention
This is the sort of error that may occur when the compiled program runs. The user may have deleted a key data file, the file may be mounted remotely on a network that is down, or the file may be on a floppy disk that is not inserted in the floppy drive. Because the parameter in these cases might sometimes be valid, the routine should not merely stop. Instead, it should raise an error and let the calling routine try to figure out what the problem is. In this example, the calling routine might display a warning and let the user decide whether to retry the file operation or cancel it. If the file is on a missing floppy disk, the user may be able to insert the disk. Then the program could retry the operation and continue successfully. A routine should never quietly ignore an invalid parameter and take some reasonable default action. Invalid parameters indicate either a problem in the code (the calling routine has a bug) or a problem in the environment (a file is missing). In either case, you should bring the problem to someones attention so it can be fixed. Highlight the problem instead of hiding it. Use Tight RestrictionsRestrictions make bugs obvious. When a bug violates the restrictions, it is easy to tell there is a problem. To catch as many bugs as possible, use the tightest restrictions that are acceptable. Later, if there is a proven need for looser restrictions, you can loosen them. For instance, suppose the PlotArray subroutine shown in the following code displays a bar graph of data values on a forms background. PlotArray requires that the number of values it is passed be between 10 and 20. That restriction was chosen somewhat arbitrarily. A program may want to display fewer values, but the result would look a bit empty. A program may also want to display more values, but the form would look crowded. Requiring between 10 and 20 values is reasonable lacking any other information. If it later becomes necessary for the program to display a graph of 50 values, the restriction can be loosened. Until then, the restriction remains tight to guard against obviously invalid values like 2 or 10,000.
Private Sub PlotValues(values() As Single)
Dim num_values As Integer
Dim min_value As Single
Dim max_value As Single
Dim i As Integer
Verify that there are between 10 and 20 values.
num_values = UBound(values) - LBound(values) + 1
If num_values < 10 Or num_values > 20 Then Stop
Find the biggest and smallest values.
min_value = values(LBound(values))
max_value = min_value
For i = LBound(values) + 1 To UBound(values)
If min_value > values(i) Then min_value = values(i)
If max_value < values(i) Then max_value = values(i)
Next i
Set the forms Scale properties.
ScaleLeft = LBound(values) - 1
ScaleWidth = UBound(values) - ScaleLeft
ScaleTop = max_value
ScaleHeight = min_value - ScaleTop
Plot the values.
For i = LBound(values) To UBound(values)
FillStyle = (i Mod 7) + 1
Line (i - 1, min_value)-(i, values(i)), , B
Next i
End Sub
To make as many bugs as possible instantly visible, start with tight restrictions and loosen them only when absolutely necessary. Use LBound and UBoundChapter 4, Constants and Enums, recommends that you use constants to define array bounds. For example, the following code uses a constant to declare an array and then initialize its elements to random values between 1 and 99.
Option Explicit
Private Const NUM_VALUES = 10
Private Values(1 To NUM_VALUES) As Integer
Initialize the random values.
Private Sub Form_Load()
InitializeValues
End Sub
Initialize the Values array with random numbers
between 1 and 99.
Private Sub InitializeValues()
Dim i As Integer
Randomize
For i = 1 To NUM_VALUES
Values(i) = Int(99 * Rnd + 1)
Next i
End Sub
The constant NUM_VALUES makes this code easy to modify. If you change NUM_VALUES to 100, you do not need to modify the InitializeValues subroutine. Because the routine uses the constant to determine the arrays upper bound, it will automatically use the new upper bound if you change it. However, the InitializeValues routine does contain the hard-coded value 1 as the arrays lower bound. If you change the arrays lower bound to 0 or some other value, the subroutine will not work properly. You could create new FIRST_VALUE and LAST_VALUE constants giving the arrays bounds, but that would be needlessly complicated. A better solution is to make subroutines like InitializeValues use LBound and UBound to determine the arrays bounds. Then no matter how you change the arrays bounds, the routine will function correctly. In fact, this routine will work even if the array is dynamically resized using the ReDim statement so it has bounds 100 and 75.
Initialize the Values array with random numbers
between 1 and 99.
Private Sub InitializeValues()
Dim i As Integer
Randomize
For i = LBound(Values) To UBound(Values)
Values(i) = Int(99 * Rnd + 1)
Next i
End Sub
Using this technique, only the code that actually declares the array needs to refer to constants or hard-coded values giving the arrays bounds. All other routines can use LBound and UBound to determine the arrays current bounds. When you write routines like this one, carefully consider how the routine will react to typical and unusual upper and lower bounds. For example, how will the routine behave if the lower bound is 0 or 1? What if both bounds are negative? Can it handle the case when the upper and lower bounds are the same? Notice also that UBound and LBound are undefined for arrays that have not been allocated. For example, the following code generates a subscript out of range error when it tries to determine LBound(Values) and UBound(Values).
Option Explicit
Private Const NUM_VALUES = 10
Private Values() As Integer
Initialize the random values.
Private Sub Form_Load()
InitializeValues
End Sub
Initialize the Values array with random numbers
between 1 and 99.
Private Sub InitializeValues()
Dim i As Integer
Randomize
For i = LBound(Values) To UBound(Values)
Values(i) = Int(99 * Rnd + 1)
Next i
End Sub
|
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.
|